/*************************************************************************
	> File Name: threadsafe_queue.h
	> Author: 
	> Mail: 
	> Created Time: 2017年04月20日 10时27分33秒 CST
 ************************************************************************/
#pragma once
#include <queue>  
#include <mutex>  
#include <condition_variable>  
#include "../base/base.h"  
  
namespace berry{
//注意：只是锁住了方法本身的调用，没锁queue容器
template<class Type>  
/*消息队列实现*/  
class ConcurrentQueue:public nocopyable{  
public:  
    ConcurrentQueue() : _queue(), _mutex(), _condition() { }  

    virtual ~ConcurrentQueue() { }  

    void Push(Type record) {  
        std::lock_guard <std::mutex> lock(_mutex);              //自解锁，创建对象时上锁，析构对象时解锁
        _queue.push(record);  
        _condition.notify_one();                                //通知其他一个正在调用wait的线程解除阻塞
    }  

    bool Pop(Type& record, bool isBlocked = true) {             //true时为阻塞，
        if (isBlocked) {  
            std::unique_lock <std::mutex> lock(_mutex);  
            while (_queue.empty()) {  
                _condition.wait(lock);  
            }  
        }  
        else // If user wants to retrieve data in non-blocking mode  
        {  
            std::lock_guard <std::mutex> lock(_mutex);  
            if (_queue.empty()) {  
                return false;  
            }  
        }  

        record = std::move(_queue.front());  
        _queue.pop();  
        return true;  
    }  

    int32_t Size() {  
        std::lock_guard <std::mutex> lock(_mutex);  
        return _queue.size();  
    }  

    bool Empty() {  
        std::lock_guard <std::mutex> lock(_mutex);  
        return _queue.empty();  
    }  

private:  
    std::queue <Type> _queue;                                   //队列
    mutable std::mutex _mutex;                                  //锁  
    std::condition_variable _condition;                         //条件变量和锁配合使用  
};  
}
